home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Remember.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  10KB  |  534 lines

  1. /*
  2. **    Remember.c
  3. **
  4. **    Login learn routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* How many characters to remember.*/
  17.  
  18. #define REMEMBER_OUT    40
  19. #define REMEMBER_IN        256
  20.  
  21.     /* The size of the aux buffer.*/
  22.  
  23. #define RECORD_AUX_BUFFER_LENGTH 1024
  24.  
  25.     /* Yet another node variant.*/
  26.  
  27. struct RecordNode
  28. {
  29.     struct Node        Node;
  30.     struct timeval    Time;
  31. };
  32.  
  33.     /* What type of text was recorded.*/
  34.  
  35. enum    {    RECORD_OUTPUT,RECORD_INPUT };
  36.  
  37.     /* The last ten bytes received.*/
  38.  
  39. STATIC UBYTE             RememberOutputData[2 * REMEMBER_OUT + 10];
  40. STATIC WORD                 RememberOutputSize;
  41.  
  42.     /* The last 256 bytes sent.*/
  43.  
  44. STATIC UBYTE             RememberInputData[2 * REMEMBER_IN + 10];
  45. STATIC WORD                 RememberInputSize;
  46.  
  47.     /* The name of the BBS we are currently recording for.*/
  48.  
  49. STATIC UBYTE             RecordName[50];
  50.  
  51.     /* Recorded lines.*/
  52.  
  53. STATIC struct List        *RecordList;
  54. STATIC LONG                 RecordCount;
  55.  
  56.     /* Auxilary data.*/
  57.  
  58. STATIC STRPTR             RecordAuxBuffer;
  59.  
  60.     /* Start of recording.*/
  61.  
  62. STATIC struct timeval     RecordTime;
  63.  
  64.     /* FinishRecord():
  65.      *
  66.      *    Finish the recording process, store the
  67.      *    recorded data in a file.
  68.      */
  69.  
  70. VOID
  71. FinishRecord()
  72. {
  73.     if(RecordCount)
  74.     {
  75.         UBYTE                     DummyBuffer[MAX_FILENAME_LENGTH];
  76.         struct FileRequester    *FileRequest;
  77.  
  78.         BlockWindows();
  79.  
  80.         if(RecordName[0])
  81.             strcpy(DummyBuffer,RecordName);
  82.         else
  83.         {
  84.             strcpy(DummyBuffer,LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT));
  85.  
  86.             strcpy(RecordName,DummyBuffer);
  87.         }
  88.  
  89.         FixName(DummyBuffer);
  90.  
  91.         DummyBuffer[27] = 0;
  92.  
  93.         LimitedStrcat(sizeof(DummyBuffer),DummyBuffer,".term");
  94.  
  95.         if(FileRequest = SaveFile(Window,LocaleString(MSG_SAVE_RECORDED_FILE_TXT),NULL,"#?.(term|rexx)",DummyBuffer,sizeof(DummyBuffer)))
  96.         {
  97.             BPTR            FileHandle;
  98.             LONG            Error = 0;
  99.             struct timeval    Delta = { 0,0 };
  100.  
  101.             FreeAslRequest(FileRequest);
  102.  
  103.             if(FileHandle = Open(DummyBuffer,MODE_NEWFILE))
  104.             {
  105.                 PhoneEntry *ActiveEntry;
  106.  
  107.                 SetIoErr(0);
  108.  
  109.                 if(FPrintf(FileHandle,LocaleString(MSG_RECORDFILE_HEADER_TXT),RecordName) < 1)
  110.                     Error = IoErr();
  111.  
  112.                 if(!Error)
  113.                 {
  114.                     struct RecordNode *Node;
  115.                     BOOL UsesSpace,UsesQuotes;
  116.                     STRPTR Header;
  117.                     LONG i,Len;
  118.  
  119.                     for(Node = (struct RecordNode *)RecordList->lh_Head ; Node->Node.ln_Succ && !Error ; Node = (struct RecordNode *)Node->Node.ln_Succ)
  120.                     {
  121.                         if(Delta.tv_secs != Node->Time.tv_secs)
  122.                         {
  123.                             LONG Secs;
  124.  
  125.                             Secs = (3 * Node->Time.tv_secs) / 2 + (3 * Node->Time.tv_micro) / 2000000;
  126.  
  127.                             SetIoErr(0);
  128.  
  129.                             if(FPrintf(FileHandle,"TIMEOUT %ld\n",Secs) < 1)
  130.                             {
  131.                                 Error = IoErr();
  132.  
  133.                                 break;
  134.                             }
  135.                             else
  136.                                 Delta = Node->Time;
  137.                         }
  138.  
  139.                         SetIoErr(0);
  140.  
  141.                             /* Now things get a little difficult.As the ARexx */
  142.                             /* parser is bound to get into trouble with trailing */
  143.                             /* and leading spaces and `trouble' will appear like */
  144.                             /* a picnic if a double quote shows up in the text, */
  145.                             /* we need to find out about these exceptions. */
  146.  
  147.                         Len = strlen(Node->Node.ln_Name);
  148.  
  149.                         for(i = 0, UsesSpace = UsesQuotes = FALSE ; i < Len ; i++)
  150.                         {
  151.                             if(Node->Node.ln_Name[i] == ' ' && (i == 0 || i == Len - 1))
  152.                             {
  153.                                 UsesSpace = TRUE;
  154.  
  155.                                 if(UsesQuotes)
  156.                                     break;
  157.                             }
  158.  
  159.                             if(Node->Node.ln_Name[i] == '\"')
  160.                             {
  161.                                 UsesQuotes = TRUE;
  162.  
  163.                                 if(UsesSpace)
  164.                                     break;
  165.                             }
  166.                         }
  167.  
  168.                         if(Node->Node.ln_Type == RECORD_OUTPUT)
  169.                             Header = "WAIT";
  170.                         else
  171.                             Header = "SEND";
  172.  
  173.                         if(FPrintf(FileHandle,"%s TEXT \"",Header) < 1)
  174.                             Error = IoErr();
  175.                         else
  176.                         {
  177.                             if(UsesSpace || UsesQuotes)
  178.                             {
  179.                                 STRPTR From,String,First,Last;
  180.                                 UBYTE c;
  181.  
  182.                                 From = String = (STRPTR)Node->Node.ln_Name;
  183.  
  184.                                 First = String;
  185.                                 Last = String + Len - 1;
  186.  
  187.                                 c = 0;
  188.  
  189.                                 while(*String)
  190.                                 {
  191.                                     switch(*String)
  192.                                     {
  193.                                         case ' ':
  194.  
  195.                                             if(String == First || String == Last)
  196.                                                 c = ' ';
  197.  
  198.                                             break;
  199.  
  200.                                         case '\"':
  201.  
  202.                                             c = '\"';
  203.                                             break;
  204.                                     }
  205.  
  206.                                     if(c)
  207.                                     {
  208.                                         STRPTR Code;
  209.  
  210.                                         if(From < String)
  211.                                         {
  212.                                             LONG Len = (LONG)(String - From);
  213.  
  214.                                             if(FWrite(FileHandle,From,Len,1) != 1)
  215.                                             {
  216.                                                 Error = IoErr();
  217.                                                 break;
  218.                                             }
  219.                                         }
  220.  
  221.                                         if(c == ' ')
  222.                                             Code = "\\*32";
  223.                                         else
  224.                                             Code = "\\*34";
  225.  
  226.                                         if(FPrintf(FileHandle,Code) < 1)
  227.                                         {
  228.                                             Error = IoErr();
  229.                                             break;
  230.                                         }
  231.  
  232.                                         From = String + 1;
  233.                                         c = 0;
  234.                                     }
  235.  
  236.                                     String++;
  237.                                 }
  238.  
  239.                                 if(!Error && From < String)
  240.                                 {
  241.                                     LONG Len = (LONG)(String - From);
  242.  
  243.                                     if(FWrite(FileHandle,From,Len,1) != 1)
  244.                                         Error = IoErr();
  245.                                 }
  246.                             }
  247.                             else
  248.                             {
  249.                                 if(FPrintf(FileHandle,Node->Node.ln_Name) < 1)
  250.                                     Error = IoErr();
  251.                             }
  252.  
  253.                             if(!Error)
  254.                             {
  255.                                 if(FPrintf(FileHandle,"\"\n") < 1)
  256.                                     Error = IoErr();
  257.                             }
  258.                         }
  259.                     }
  260.                 }
  261.  
  262.                 Close(FileHandle);
  263.  
  264.                 if(ActiveEntry = LockActiveEntry(GlobalPhoneHandle))
  265.                 {
  266.                     if(ShowRequest(Window,LocaleString(MSG_USE_AS_LOGIN_SCRIPT_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),ActiveEntry->Header->Name))
  267.                     {
  268.                         if(!ActiveEntry->Config->CommandConfig)
  269.                         {
  270.                             if(!CreateConfigEntry(ActiveEntry->Config,PREF_COMMAND))
  271.                                 ShowError(Window,ERROR_NO_FREE_STORE,NULL,NULL);
  272.                         }
  273.  
  274.                         if(ActiveEntry->Config->CommandConfig)
  275.                         {
  276.                             PhonebookChanged = TRUE;
  277.  
  278.                             LimitedSPrintf(sizeof(ActiveEntry->Config->CommandConfig->LoginMacro),ActiveEntry->Config->CommandConfig->LoginMacro,"\\a %s",DummyBuffer);
  279.                         }
  280.                     }
  281.  
  282.                     UnlockActiveEntry(GlobalPhoneHandle);
  283.                 }
  284.             }
  285.             else
  286.                 Error = IoErr();
  287.  
  288.             if(!Error && Config->MiscConfig->CreateIcons && IconBase)
  289.             {
  290.                 struct DiskObject *Icon;
  291.  
  292.                 if(!(Icon = GetDiskObject("ENV:def_term")))
  293.                 {
  294.                     if(!(Icon = GetDiskObject("ENV:def_rexx")))
  295.                     {
  296.                         if(Icon = GetDefDiskObject(WBPROJECT))
  297.                             Icon->do_DefaultTool = "RX";
  298.                     }
  299.                 }
  300.  
  301.                 if(Icon)
  302.                 {
  303.                     Icon->do_CurrentX = Icon->do_CurrentY = NO_ICON_POSITION;
  304.  
  305.                     PutDiskObject(DummyBuffer,Icon);
  306.  
  307.                     FreeDiskObject(Icon);
  308.                 }
  309.             }
  310.  
  311.             if(Error)
  312.                 ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  313.         }
  314.  
  315.         DeleteRecord();
  316.  
  317.         ReleaseWindows();
  318.     }
  319. }
  320.  
  321.     /* CreateRecord(STRPTR BBSName):
  322.      *
  323.      *    Start recording incoming and outgoing text.
  324.      */
  325.  
  326. BOOL
  327. CreateRecord(STRPTR BBSName)
  328. {
  329.     DeleteRecord();
  330.  
  331.     if(RecordList = CreateList())
  332.     {
  333.         if(RecordAuxBuffer = (STRPTR)AllocVecPooled(RECORD_AUX_BUFFER_LENGTH,MEMF_ANY))
  334.         {
  335.             strcpy(RecordName,BBSName);
  336.  
  337.             GetSysTime(&RecordTime);
  338.  
  339.             return(TRUE);
  340.         }
  341.  
  342.         FreeVecPooled(RecordList);
  343.  
  344.         RecordList = NULL;
  345.     }
  346.  
  347.     return(FALSE);
  348. }
  349.  
  350.     /* DeleteRecord():
  351.      *
  352.      *    Stop recording, free auxilary buffers.
  353.      */
  354.  
  355. VOID
  356. DeleteRecord()
  357. {
  358.     FreeVecPooled(RecordAuxBuffer);
  359.     RecordAuxBuffer = NULL;
  360.  
  361.     DeleteList(RecordList);
  362.     RecordList = NULL;
  363.  
  364.     RecordCount = 0;
  365. }
  366.  
  367.     /* RememberResetOutput():
  368.      *
  369.      *    Reset output monitoring.
  370.      */
  371.  
  372. VOID
  373. RememberResetOutput()
  374. {
  375.     RememberOutputSize = 0;
  376. }
  377.  
  378.     /* RememberOutputText(STRPTR String,LONG Size):
  379.      *
  380.      *    Remember the last ten characters received.
  381.      */
  382.  
  383. VOID
  384. RememberOutputText(STRPTR String,LONG Size)
  385. {
  386.     if(Size >= REMEMBER_OUT)
  387.     {
  388.         CopyMem(String + Size - REMEMBER_OUT,RememberOutputData,REMEMBER_OUT);
  389.  
  390.         RememberOutputSize = REMEMBER_OUT;
  391.     }
  392.     else
  393.     {
  394.         if(RememberOutputSize + Size > REMEMBER_OUT)
  395.         {
  396.             LONG Delta = RememberOutputSize + Size - REMEMBER_OUT,i;
  397.  
  398.             for(i = 0 ; i < RememberOutputSize - Delta ; i++)
  399.                 RememberOutputData[i] = RememberOutputData[Delta + i];
  400.  
  401.             while(i < REMEMBER_OUT)
  402.                 RememberOutputData[i++] = *String++;
  403.  
  404.             RememberOutputSize = REMEMBER_OUT;
  405.         }
  406.         else
  407.         {
  408.             CopyMem(String,&RememberOutputData[RememberOutputSize],Size);
  409.  
  410.             RememberOutputSize += Size;
  411.         }
  412.     }
  413. }
  414.  
  415.     /* RememberResetInput():
  416.      *
  417.      *    Reset input monitoring.
  418.      */
  419.  
  420. VOID
  421. RememberResetInput()
  422. {
  423.     RememberInputSize = 0;
  424. }
  425.  
  426.     /* RememberInputText(STRPTR String,LONG Size):
  427.      *
  428.      *    Remember the last 256 characters sent.
  429.      */
  430.  
  431. VOID
  432. RememberInputText(STRPTR String,LONG Size)
  433. {
  434.     if(Size >= REMEMBER_IN)
  435.     {
  436.         CopyMem(String + Size - REMEMBER_IN,RememberInputData,REMEMBER_IN);
  437.  
  438.         RememberInputSize = REMEMBER_IN;
  439.     }
  440.     else
  441.     {
  442.         if(RememberInputSize + Size > REMEMBER_IN)
  443.         {
  444.             LONG Delta = RememberInputSize + Size - REMEMBER_IN,i;
  445.  
  446.             for(i = 0 ; i < RememberInputSize - Delta ; i++)
  447.                 RememberInputData[i] = RememberInputData[Delta + i];
  448.  
  449.             while(i < REMEMBER_IN)
  450.                 RememberInputData[i++] = *String++;
  451.  
  452.             RememberInputSize = REMEMBER_IN;
  453.         }
  454.         else
  455.         {
  456.             CopyMem(String,&RememberInputData[RememberInputSize],Size);
  457.  
  458.             RememberInputSize += Size;
  459.         }
  460.     }
  461. }
  462.  
  463.     /* RememberSpill():
  464.      *
  465.      *    `Spill' the collected text, put it into the list.
  466.      */
  467.  
  468. VOID
  469. RememberSpill()
  470. {
  471.     if(RecordList)
  472.     {
  473.         struct RecordNode    *Node;
  474.         struct timeval         Delta,Backup;
  475.  
  476.             /* Calculate the difference in time
  477.              * between the last line stored and this
  478.              * line getting stored.
  479.              */
  480.  
  481.         GetSysTime(&Backup);
  482.  
  483.         Delta = Backup;
  484.         SubTime(&Delta,&RecordTime);
  485.  
  486.         RecordTime = Backup;
  487.  
  488.         if(!Delta.tv_secs)
  489.             Delta.tv_secs = 1;
  490.  
  491.         Delta.tv_micro = 0;
  492.  
  493.         if(RememberOutputSize)
  494.         {
  495.             TranslateBack(RememberOutputData,RememberOutputSize,RecordAuxBuffer,RECORD_AUX_BUFFER_LENGTH);
  496.  
  497.             if(Node = (struct RecordNode *)AllocVecPooled(sizeof(struct RecordNode) + strlen(RecordAuxBuffer) + 1,MEMF_ANY))
  498.             {
  499.                 Node->Node.ln_Name = (STRPTR)(Node + 1);
  500.                 Node->Node.ln_Type = RECORD_OUTPUT;
  501.  
  502.                 strcpy(Node->Node.ln_Name,RecordAuxBuffer);
  503.  
  504.                 Node->Time = Delta;
  505.  
  506.                 AddTail(RecordList,(struct Node *)Node);
  507.  
  508.                 RecordCount++;
  509.             }
  510.         }
  511.  
  512.         if(RememberInputSize)
  513.         {
  514.             TranslateBack(RememberInputData,RememberInputSize,RecordAuxBuffer,RECORD_AUX_BUFFER_LENGTH);
  515.  
  516.             if(Node = (struct RecordNode *)AllocVecPooled(sizeof(struct RecordNode) + strlen(RecordAuxBuffer) + 1,MEMF_ANY))
  517.             {
  518.                 Node->Node.ln_Name = (STRPTR)(Node + 1);
  519.                 Node->Node.ln_Type = RECORD_INPUT;
  520.  
  521.                 strcpy(Node->Node.ln_Name,RecordAuxBuffer);
  522.  
  523.                 Node->Time = Delta;
  524.  
  525.                 AddTail(RecordList,(struct Node *)Node);
  526.  
  527.                 RecordCount++;
  528.             }
  529.         }
  530.     }
  531.  
  532.     RememberOutputSize = RememberInputSize = 0;
  533. }
  534.